.TH MPX 2 
.SH NAME
mpx \- create and manipulate multiplexed files
.SH SYNOPSIS
.B mpx(name, access)
.B char *name;
.PP
.B join(fd, xd)
.PP
.B chan(xd)
.PP
.B extract(i, xd)
.PP
.B attach(i, xd)
.PP
.B detach(i, xd)
.PP
.B connect(fd, cd, end)
.PP
.B npgrp(i, xd, pgrp)
.PP
.B ckill(i, xd, signal)
.PP
.B #include <sys/mx.h>
.br
.B mpxcall(cmd, vec)
.br
.B int *vec;
.SH DESCRIPTION
.PP
.B mpxcall(cmd, vec)
is the system call shared by the 
library routines described below.
.I Cmd
selects a command using values
defined in
.IR <sys/mx.h> .
.I Vec
is the address of a
structure containing the arguments
for the command.
.PP
.B mpx(name, access)
.PP
.I Mpx
creates and opens the file 
.I name
with access permission
.I access
(see
.IR creat (2))
and returns a file descriptor available for
reading and writing.
A \-1 is returned if the file cannot be created,
if
.I name
already exists, or
if the file table or other operating system
data structures are full.
The file descriptor is required for use
with other routines.
.PP
If
.I name
designates a null string,
a file descriptor is returned as described
but no entry is created in the file system.
.PP
Once created an mpx file may be opened
(see
.IR open (2))
by any process.
This provides a form of interprocess communication
whereby a process B can `call' process A
by opening an mpx file 
created by A.
To B, the file is ordinary with one exception:
the
.I connect
primitive could be applied to it.
Otherwise the functions
described below are used only in process A
and descendants that inherit the open mpx file.
.PP
When a process opens an mpx file, the owner of the
file receives a control message when the file is next read.
The method for `answering' 
this kind of call involves 
using
.I attach
and
.I detach
as described in more detail below.
.PP
Once B has opened A's mpx file
it is said to have a
.I channel
to A.
A channel is a pair of data streams:
in this case, one from B to A and the
other from A to B.
Several processes may open the same mpx file
yielding multiple channels within the one mpx file.
By accessing the appropriate channel,
A can communicate with B and any others.
When A reads (see
.IR read (2))
from the mpx file
data written to A by the other processes appears
in A's buffer using a record format
described in
.IR mpxio (5).
When A writes (see
.IR write (2))
on its mpx file the data must be formatted in a similar way.
.PP
The following commands
are used to manipulate mpx files and channels.
.IP
.IR join \-
adds a new channel on an mpx file to an open file F.
I/O on the new channel is I/O on F.
.br
.IR chan \-
creates a new channel.
.br
.IR extract \-
file descriptor maintenance.
.br
.IR connect \-
similar to join except that the open file F is connected
to an existing channel.
.br
.I attach
and
.IR detach \-
used with call protocol.
.br
.IR npgrp \-
manipulates process group numbers so that a channel
can act as a control terminal (see
.IR tty (4)).
.br
.IR ckill \-
send signal (see
.IR signal (2))
to process group through channel.
.PP
A maximum of 15 channels may be connected to an
mpx file.
They are numbered 0 through 14.
.I Join
may be used to make one mpx file appear as a channel
on another mpx file.
A hierarchy or tree of mpx files may be set up in this way.
In this case
one of the mpx files must be the root of a tree
where the other mpx files are interior nodes.
The maximum depth of such a tree
is 4.
.PP
An
.I index
is a 16-bit value
that denotes a location
in an mpx tree other than the root:
the path through mpx `nodes' from the root
to the location is expressed as a sequence of
4-bit nibbles.
The branch taken at the root is represented by
the low-order 4-bits of an index.
Each succeeding branch is specified by the next
higher-order nibble.
If the length of a path to be expressed
is less than 4,
then the illegal channel number, 15,
must be used to terminate the sequence.
This is not strictly necessary for the
simple case of a tree consisting of
only a root node: its channels
can be expressed by the numbers
0 through 14.
An index
.I i
and file descriptor
.I xd
for the root of an mpx tree are
required as arguments to most
of the commands described below.
Indices also serve as channel identifiers
in the record formats given in
.IR mpxio (5).
Since -1 is not a valid index,
it can be returned as a error indication
by subroutines that normally return
indices.
.PP
The operating system informs the process managing an mpx file
of changes in the status of channels attached to the file
by generating messages that
are read along with data from the channels.
The form and content of these messages is described
in
.IR mpxio (5).
.PP
.B join(fd, xd)
establishes a connection (channel) between an mpx file
and another object.
.I Fd
is an open file descriptor for a character device
or an mpx file and
.I xd
is the file descriptor of an
mpx file.
.I Join
returns the index for the new channel
if the operation succeeds and \-1
if it does not.
.PP
Following  join,
.I fd
may still be used in any system call that would
have been meaningful before the join operation.
Thus
a process can read and write directly to
.I fd
as well as access it via
.I xd.
If the number of channels
required for a tree of mpx files
exceeds the number of open files
permitted a process by the operating system,
some of the file descriptors can be released using
the standard  
.IR close (2)
call.
Following a close on an active file descriptor for a channel
or internal mpx node,
that object may still be accessed through the root of the
tree.
.PP
.B chan(xd)
allocates a channel and connects
one end of it to the mpx file
represented by file descriptor
.I xd.
.I Chan
returns the index of the new channel or
a \-1 indicating failure.
The
.I extract
primitive can be used to get a non-multiplexed
file descriptor for the free end of a channel
created by
.I chan.
.PP
Both
.I chan
and
.I join
operate on the mpx file specified by
.IR xd .
File descriptors for interior nodes of an
mpx tree must be preserved or reconstructed with
.I extract
for use with
.I join
or
.IR chan .
For the remaining commands described here,
.I xd
denotes the file descriptor for the
root of an mpx tree.
.PP
.B Extract(i, xd)
returns a file descriptor for the object with
index
.I i
on the mpx tree with root file descriptor
.I xd.
A \-1 is returned by extract if a file descriptor is not available
or if the arguments do not refer to an existing
channel and mpx file.
.PP
.B attach(i, xd)
.br
.BR "detach(i, xd)" .
If a process A has created an mpx file represented
by file descriptor
.I xd,
then a process B
can open (see
.IR open (2))
the mpx file.
The purpose is to establish a channel between
A and B through the mpx file.
.I Attach
and 
.I Detach
are used by A to respond to
such opens.
.PP
An open request by B fails immediately if a 
new channel cannot be allocated on the mpx file,
if the mpx file does not exist,
or if it does exist
but there is no process (A)
with a multiplexed file descriptor
for the mpx file
(i.e.
.I xd
as returned by
.IR mpx (2)).
Otherwise a channel
with index number
.I i
is allocated.
The next time A reads on file descriptor
.IR xd ,
the WATCH control message
(see
.IR mpxio (5))
will be delivered on channel
.I i.
A  responds to this message with
.I attach
or 
.I detach.
The former causes the open to complete and
return a file descriptor to B.
The latter deallocates channel
.I i
and causes the open to fail.
.PP
One mpx file may be placed in `listener' mode.
This is done by writing
.I "ioctl(xd, MXLSTN, 0)"
where
.I xd
is an mpx file descriptor
and MXLSTN is defined in 
.IR /usr/include/sgtty.h .
The semantics of listener mode are that
all file names discovered by 
.IR open (2)
to have 
the syntax
.I "system!pathname"
(see
.IR uucp (1))
are treated as opens on the mpx file.
The operating system sends the listener process 
an OPEN message (see
.IR mpxio (5))
which includes the file name being opened.
.I Attach
and
.I detach
then apply as described above.
.PP
.I Detach
has two other uses:
it closes and releases the resources
of any active channel it is applied to,
and should be used to respond to
a CLOSE message (see
.IR mpxio (5))
on a channel so the channel may be reused.
.PP
.BR "connect(fd, cd, end)" .
.I Fd
is a character file descriptor and
.I cd
is a file descriptor for a channel,
such as might be obtained via
.I "extract( chan(xd), xd)"
or by
.IR open (2)
followed by
.I attach.
.I Connect
splices the two streams together.
If
.I end
is negative, only
the output of
.I fd
is spliced to the input of
.I cd.
If
.I end
is positive, the output of
.I cd
is spliced to the input of
.I fd.
If
.I end
is zero, then both splices are made.
.PP
.BR "npgrp(i, xd, pgrp)" .
If
.I xd
is negative
.I npgrp
applies to the process executing it,
otherwise
.I i
and
.I xd
are interpreted as a channel index and
mpx file descriptor
and
.I npgrp
is applied to the process on the
non-multiplexed end of the channel.
If
.I pgrp
is zero, the process group number of the indicated process
is set to the process number of that process,
otherwise the value of
.I pgrp
is used as the process group number.
.PP
.I Npgrp
normally returns the new process group number.
If
.I i
and
.I xd
specify  a nonexistant channel,
.I npgrp
returns \-1.
.PP
.B ckill(i, xd, signal)
sends the specified signal (see
.IR signal (2))
through the channel specified by
.I i
and
.I xd.
If the channel is connected to anything other
than a process,
.I ckill
is a null operation.
If there is a process at the other end of the channel,
the process group will be interrupted (see
.IR signal (2),
.IR kill (2)).
.I Ckill
normally returns 
.I signal.
If
.I ch
and
.I xd
specify a nonexistent channel,
.I ckill
returns \-1.
.SH FILES
/usr/include/sys/mx.h
.br
/usr/include/sgtty.h
.SH "SEE ALSO"
mpxio(5)
.SH BUGS
.PP
Mpx files are an experimental part of the operating
system more subject to change and prone to bugs
than other parts.
Maintenance programs, e.g.
.IR icheck (1),
diagnose mpx files as  an illegal mode.
Channels may only be connected to objects in the operating
system that are accessible through the line discipline
mechanism.
Higher performace line disciplines are needed.
The maximum tree depth restriction is not really checked.
A non-destructive
.I disconnect
primitive (inverse of
.IR connect )
is not provided.
A non-blocking flow control strategy
based on messages defined in
.IR mpxio (5)
should not be attempted by novices;
the enabling
.I ioctl
command should be protected.
The
.I join
operation could be subsumed by
.I connect.
A mechanism is needed for moving a channel from one
location in an mpx tree to another.
